#include <iostream>
#include <vector>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <functional>

const int TASKNUM = 3;
using HandlerThread = void*(*)(void*);

class PthreadData
{
public:
    PthreadData(const std::string& s)
        :_pthreadName(s)
    {}
    std::string GetThreadName()
    {
        return _pthreadName;
    }
private:
    std::string _pthreadName;
};

class Result
{
public:
    Result(const std::string& name, const std::string& message)
        :_pthreadName(name)
        ,_resultMessage(message)
    {}
    std::string GetThreadName()
    {
        return _pthreadName;
    }
    std::string GetResultMessage()
    {
        return _resultMessage;
    }
private:
    std::string _pthreadName;
    std::string _resultMessage;
};

void* ReloadConf(void* args)
{
    sleep(10);
    PthreadData* pd = static_cast<PthreadData*>(args);
    std::string message = pd->GetThreadName() + " is reloading config(1)......";
    Result* re = new Result(pd->GetThreadName(), message);
    return static_cast<void*>(re);
};

void* ConnectMysql(void* args)
{
    sleep(10);
    PthreadData* pd = static_cast<PthreadData*>(args);
    std::string message = pd->GetThreadName() + " is connecting mysql(2)......";
    Result* re = new Result(pd->GetThreadName(), message);
    return static_cast<void*>(re);
};

void* GetNetworkInfo(void* args)
{
    sleep(10);
    PthreadData* pd = static_cast<PthreadData*>(args);
    std::string message = pd->GetThreadName() + " is geting network message(3)......";
    Result* re = new Result(pd->GetThreadName(), message);
    return static_cast<void*>(re);
};

HandlerThread tasks[TASKNUM] = { ReloadConf, ConnectMysql, GetNetworkInfo };


int main()
{
    std::cout << "pid : " << getpid() << std::endl;
    const int N = 5;
    std::vector<pthread_t> threads(N);
    std::vector<PthreadData*> pthreadData(N);
    int taskCnt = 0;
    //创建线程
    for (int i = 0; i < N; i++)
    {
        char buff[256];
        snprintf(buff, sizeof(buff) - 1, "thread-%d", i + 1);
        pthread_t tid;
        pthreadData[i]= new PthreadData(buff);
        pthread_create(&threads[i], nullptr, tasks[taskCnt++], pthreadData[i]);
        taskCnt %= TASKNUM;
    }
    //等待线程并获取结果
    void* ret = nullptr;
    for (auto thread : threads)
    {
        pthread_join(thread, &ret);
        Result* re = static_cast<Result*>(ret);
        std::cout << re->GetThreadName() << " : " << re->GetResultMessage() << std::endl;
        delete re;
        sleep(1);
    }
    for (auto ptr : pthreadData)
    {
        delete ptr;
    }

    return 0;
}






// std::string ToHEX(pthread_t tid)
// {
//     char id[64];
//     snprintf(id, sizeof(id) - 1, "0x%lx", tid);
//     return id;
// }

// void* threadrun(void*)
// {
//     int cnt = 5;
//     while(cnt--)
//     {
//         std::cout << "I am new thread, pid : " << getpid() 
//         <<", thread id : " << ToHEX(pthread_self()) << std::endl;
//         sleep(1);
//     }
//     //pthread_exit(reinterpret_cast<void*>(1));
//     return reinterpret_cast<void*>(123);
// }

// int main()
// {
//     pthread_t tid;
//     //tid是输出型参数，返回新线程的tid
//     pthread_create(&tid, nullptr, threadrun, nullptr);
//     // int cnt = 5;
//     // while(cnt--)
//     // {
//     //     std::cout << "I am main thread, pid : " << getpid() 
//     //     << ", new thread id : " << ToHEX(tid) 
//     //     << ", main thread id : " << ToHEX(pthread_self())<< std::endl;
//     //     sleep(1);
//     // }
//     sleep(2);
    
//     //在main线程中，确定新线程已经启动的前提下，新线程的返回值位-1，即为PTHREAD_CANCELED
//     pthread_cancel(tid);
//     void* ret = nullptr;
//     int n = pthread_join(tid, &ret);
//     std::cout << "main wait newd success, main quit, ret : " << reinterpret_cast<long long>(ret) << std::endl;

//     return 0;
// }